package com.demo.sso.common.config;

import com.demo.sso.shiro.UserRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.Map;

//import org.apache.shiro.web.mgt.DefaultWebSecurityManager;

/**
 * 请添加模块注释
 *
 * @author fengjy
 * @date 2018-10-29 20:01
 */

@Configuration
public class ShiroConfig {

    @Resource
    private UserRealm userRealm;
    /**
     * 配置shiro过滤器
     * @author fengjy
     */
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager")SecurityManager securityManager) {
        // 1.定义shiroFactoryBean
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        // 2.设置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 3.LinkedHashMap是有序的，进行顺序拦截器配置
        Map<String,String> filterChainMap = new LinkedHashMap<String,String>();
        // 4.配置logout过滤器
        filterChainMap.put("/logout", "logout");

        // 登陆和主页不需要认证
        filterChainMap.put("/login.html","anon");
        filterChainMap.put("/index.html","anon");
        filterChainMap.put("/author/login","anon");
//        filterChainMap.put("/loginOut","anon");

        // 不需要拦截swagger2文档资源
        filterChainMap.put("/swagger-ui.html**","anon");
        filterChainMap.put("/webjars/springfox-swagger-ui/**","anon");
        filterChainMap.put("/swagger-resources/**","anon");
        filterChainMap.put("/v2/api-docs/**","anon");


        filterChainMap.put("/","anon");
        filterChainMap.put("/css/**", "anon");      // 匿名访问静态资源
        filterChainMap.put("/js/**", "anon");       // 匿名访问静态资源
        filterChainMap.put("/fonts/**", "anon");    // 匿名访问静态资源
        filterChainMap.put("/images/**", "anon");   // 匿名访问静态资源
        filterChainMap.put("/lib/**", "anon");      // 匿名访问静态资源

        // 5.所有url必须通过认证才可以访问
        filterChainMap.put("/**","authc");

        // 6.设置默认登录的url
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        // 7.设置成功之后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index.html");
        // 8.设置未授权界面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        // 9.设置shiroFilterFactoryBean的FilterChainDefinitionMap
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
        return shiroFilterFactoryBean;
    }
    /**
     * 配置安全管理器
     * @author fengjy
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        // 设置realm的加密类型
        userRealm.setCredentialsMatcher(credentialsMatcher());

        //设置realm.
        securityManager.setRealm(userRealm); // 将自定义的realm注入到securityManager中

        // 设置sessionManager
//        securityManager.setSessionManager();

        // 设置cacheManager
//        securityManager.setCacheManager();

        // 设置是否记住我
        securityManager.setRememberMeManager(getCookieRememberMeManager());
        return securityManager;
    }

    /**
     * 设置realm的加密类型
     * @return
     */
    private HashedCredentialsMatcher credentialsMatcher () {

        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("md5"); // md5加密算法
        credentialsMatcher.setHashIterations(1); // 加密一次

        return credentialsMatcher;
    }

    private CookieRememberMeManager getCookieRememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(getSimpleCookie());
        return cookieRememberMeManager;
    }

    private SimpleCookie getSimpleCookie () {
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        // 五天内免登陆
        simpleCookie.setMaxAge(3600 * 24 * 5);
        return simpleCookie;
    }

}
